package net.goutalk.glcs.module.erpModel.caseErpUnit.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.MPJWrappers;
import net.goutalk.glcs.common.annotation.GlcsLog;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.enums.YesOrNoEnum;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.VoToColumnUtil;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.AddCaseErpUnitTypeDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnit;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnitConvert;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitConvertService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.CaseErpUnitTypeExportVo;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.CaseErpUnitTypePageDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.CaseErpUnitTypeListVo;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.CaseErpUnitTypeVo;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.UpdateCaseErpUnitTypeDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnitType;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitTypeService;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.workflow.utils.WorkFlowUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 单位类型【case_erp_unit_type】 前端控制器
 * </p>
 *
 * @author hnyyzy
 * @since 2023-06-13
 */
@RestController
@RequestMapping(GlobalConstant.CASE_ERP_UNIT +"/caseErpUnitType")
@Api(value = GlobalConstant.CASE_ERP_UNIT +"/caseErpUnitType", tags = "单位类型")
@AllArgsConstructor
public class CaseErpUnitTypeController {

    private ICaseErpUnitTypeService caseErpUnitTypeService;

    private ICaseErpUnitConvertService caseErpUnitConvertService;

    private ICaseErpUnitService caseErpUnitService;

    @GetMapping(value = "/list")
    @ApiOperation("单位类型列表")
    public R list() {
        List<CaseErpUnit> caseErpUnitList = caseErpUnitService.list();
        List<CaseErpUnitType> list = caseErpUnitTypeService.list(Wrappers.<CaseErpUnitType>query().lambda().eq(CaseErpUnitType::getState, YesOrNoEnum.YES.getCode()));

        List<CaseErpUnitTypeListVo> caseErpUnitTypeListVoList = new ArrayList<>();
        for (CaseErpUnitType caseErpUnitType : list) {
            CaseErpUnitTypeListVo caseErpUnitTypeListVo = BeanUtil.toBean(caseErpUnitType, CaseErpUnitTypeListVo.class);
            List<CaseErpUnit> collect = caseErpUnitList.stream().filter(x -> x.getUnitTypeId().equals(caseErpUnitType.getId()) && x.getIsStandard() == YesOrNoEnum.YES.getCode()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                caseErpUnitTypeListVo.setIsHaveStandard(YesOrNoEnum.YES.getCode());
            }else {
                caseErpUnitTypeListVo.setIsHaveStandard(YesOrNoEnum.NO.getCode());
            }
            caseErpUnitTypeListVoList.add(caseErpUnitTypeListVo);
        }
        return R.ok(caseErpUnitTypeListVoList);
    }

    @GetMapping(value = "/page")
    @ApiOperation("单位类型列表分页")
    public R page(CaseErpUnitTypePageDto dto) {
        if (ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())) {
            dto.setStartTime(WorkFlowUtil.getStartOfDay(dto.getStartTime()));
            dto.setEndTime(WorkFlowUtil.getEndOfDay(dto.getEndTime()));
        }
        IPage<CaseErpUnitTypeVo> page = caseErpUnitTypeService.selectJoinListPage(ConventPage.getPage(dto), CaseErpUnitTypeVo.class,
                MPJWrappers.<CaseErpUnitType>lambdaJoin()
                        .distinct()
                        .orderByDesc(CaseErpUnitType::getCreateDate)
                        .like(StrUtil.isNotBlank(dto.getName()), CaseErpUnitType::getName, dto.getName())
                        .between(ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())
                                , CaseErpUnitType::getCreateDate, dto.getStartTime(), dto.getEndTime())
                        .selectAs(User::getName, CaseErpUnitTypeVo::getCreateUserName)
                        .select(CaseErpUnitType::getId)
                        .select(CaseErpUnitType.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpUnitTypeVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, CaseErpUnitType::getCreateUserId));

        PageOutput<CaseErpUnitTypeVo> pageOutput = ConventPage.getPageOutput(page);
        return R.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询单位类型信息")
    public R info(@RequestParam Long id) {
        CaseErpUnitType caseErpUnitType = caseErpUnitTypeService.getById(id);
        if (caseErpUnitType == null) {
            R.error("找不到此单位类型！");
        }
        return R.ok(BeanUtil.toBean(caseErpUnitType, CaseErpUnitTypeVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增单位类型")
    public R add(@Valid @RequestBody AddCaseErpUnitTypeDto dto) {
        long count = caseErpUnitTypeService.count(Wrappers.<CaseErpUnitType>query().lambda().eq(CaseErpUnitType::getName, dto.getName()));
        if (count > 0) {
            return R.error("此单位类型已经存在！");
        }
        CaseErpUnitType caseErpUnitType = BeanUtil.toBean(dto, CaseErpUnitType.class);
        caseErpUnitTypeService.save(caseErpUnitType);
        return R.ok(true);
    }

    @PutMapping
    @ApiOperation(value = "修改单位类型")
    public R update(@Valid @RequestBody UpdateCaseErpUnitTypeDto dto) {
        CaseErpUnitType caseErpUnitType = BeanUtil.toBean(dto, CaseErpUnitType.class);
        caseErpUnitTypeService.updateById(caseErpUnitType);
        return R.ok(true);
    }

    @DeleteMapping
    @ApiOperation(value = "删除")
    @GlcsLog(value = "删除单位类型")
    public R delete(@Valid @RequestBody List<Long> ids) {
        for (Long id : ids) {
            long count = caseErpUnitConvertService.count(Wrappers.<CaseErpUnitConvert>query().lambda().eq(CaseErpUnitConvert::getUnitTypeId, id));
            if (count > 0) {
                return R.error("已进行单位换算配置的单位类型不能删除！");
            }
        }
        return R.ok(caseErpUnitTypeService.delete(ids));
    }

    @PostMapping(value = "/export")
    @ApiOperation(value = "导出")
    @GlcsLog(value = "导出表单数据")
    public ResponseEntity<byte[]> export(@Valid @RequestBody List<Long> ids) {
        List<CaseErpUnitTypeExportVo> caseErpUnitTypeExportVoList = caseErpUnitTypeService.selectJoinList(CaseErpUnitTypeExportVo.class,
                MPJWrappers.<CaseErpUnitType>lambdaJoin()
                        .distinct()
                        .in(CaseErpUnitType::getId, ids)
                        .selectAs(User::getName, CaseErpUnitTypeExportVo::getCreateUserName)
                        .select(CaseErpUnitType::getId)
                        .select(CaseErpUnitType.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpUnitTypeExportVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, CaseErpUnitType::getCreateUserId));
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, CaseErpUnitTypeExportVo.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(caseErpUnitTypeExportVoList);
        return R.fileStream(bot.toByteArray(), "单位类型" + ExcelTypeEnum.XLSX.getValue());
    }

    @PostMapping("/import")
    @ApiOperation(value = "导入")
    public R importData(@RequestParam MultipartFile file) throws IOException {
        List<AddCaseErpUnitTypeDto> savedDataList = EasyExcel.read(file.getInputStream()).head(AddCaseErpUnitTypeDto.class).sheet().doReadSync();
        caseErpUnitTypeService.saveBatch(BeanUtil.copyToList(savedDataList, CaseErpUnitType.class));
        return R.ok(true);
    }

    @GetMapping("/export")
    @ApiOperation(value = "下载模板")
    @SneakyThrows
    public ResponseEntity<byte[]> export() {
        List<AddCaseErpUnitTypeDto> caseErpUnitTypeList = new ArrayList<>();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, AddCaseErpUnitTypeDto.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(BeanUtil.copyToList(caseErpUnitTypeList, AddCaseErpUnitTypeDto.class));
        return R.fileStream(bot.toByteArray(), "单位类型模板" + ExcelTypeEnum.XLSX.getValue());
    }

}
